﻿using ImplementationJeu;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using InterfaceJeu;
using System.Collections.Generic;

namespace TestImplementation
{
    
    
    /// <summary>
    ///Classe de test pour VilleTest, destinée à contenir tous
    ///les tests unitaires VilleTest
    ///</summary>
    [TestClass()]
    public class VilleTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Obtient ou définit le contexte de test qui fournit
        ///des informations sur la série de tests active ainsi que ses fonctionnalités.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Attributs de tests supplémentaires
        // 
        //Vous pouvez utiliser les attributs supplémentaires suivants lorsque vous écrivez vos tests :
        //
        //Utilisez ClassInitialize pour exécuter du code avant d'exécuter le premier test dans la classe
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            ImplementationJeu.Jeu monJeu = ImplementationJeu.Jeu.Instance;
            InterfaceJeu.Joueur j1 = new ImplementationJeu.Joueur("Nicolas", System.Drawing.Color.Red, "INFO");
            InterfaceJeu.Joueur j2 = new ImplementationJeu.Joueur("Aurelien", System.Drawing.Color.Azure, "EII");
            List<InterfaceJeu.Joueur> lj = new List<InterfaceJeu.Joueur>();
            lj.Add(j1);
            lj.Add(j2);
            monJeu.demarrerNouveuJeu(lj, 25);
        }
        //Utilisez ClassCleanup pour exécuter du code après que tous les tests ont été exécutés dans une classe
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Utilisez TestInitialize pour exécuter du code avant d'exécuter chaque test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Utilisez TestCleanup pour exécuter du code après que chaque test a été exécuté
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        internal virtual ImplementationJeu.Ville CreateVille()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(0, 0));
            Civilisation civilisation = new CivilisationEII();
            ImplementationJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            return target;
        }

        /// <summary>
        ///Test pour Constructeur Ville
        ///</summary>
        [TestMethod()]
        public void VilleConstructorTest()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(0, 0));
            Civilisation civilisation = new CivilisationEII();
            InterfaceJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            Assert.AreEqual(civilisation, target.civi);
            Assert.AreEqual(c, target.caseSousLaVille);
            Assert.AreEqual(c.minerai, ((ImplementationJeu.Ville)target).minerai);
            Assert.AreEqual(c.coordo, ((ImplementationJeu.Ville)target).coordo);
            Assert.AreEqual(c.unites, ((ImplementationJeu.Ville)target).unites);
        }

        /// <summary>
        ///Test pour checkDureeProduction
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void checkDureeProductionTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            target.dureeAttenteProduction = 0;
            bool expected = true;
            bool actual;
            actual = target.checkDureeProduction();
            Assert.AreEqual(expected, actual);

            target.dureeAttenteProduction = 1;
            expected = false;
            actual = target.checkDureeProduction();
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour caseSousLaVille
        ///</summary>
        [TestMethod()]
        public void caseSousLaVilleTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            Case expected = new CasePlaine(10,10);
            Case actual;
            target.caseSousLaVille = expected;
            actual = target.caseSousLaVille;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour casesOccupees
        ///</summary>
        [TestMethod()]
        public void casesOccupeesTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            List<Case> expected = new List<Case>();
            List<Case> actual;
            target.casesOccupees = expected;
            actual = target.casesOccupees;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour civi
        ///</summary>
        [TestMethod()]
        public void civiTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            Civilisation expected = new CivilisationEII();
            Civilisation actual;
            target.civi = expected;
            actual = target.civi;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour coordo
        ///</summary>
        [TestMethod()]
        public void coordoTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            InterfaceJeu.Coordonnees expected = new ImplementationJeu.Coordonnees(22, 22);
            InterfaceJeu.Coordonnees actual;
            target.coordo = expected;
            actual = target.coordo;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour dureeAttenteProduction
        ///</summary>
        [TestMethod()]
        public void dureeAttenteProductionTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            int expected = 5;
            int actual;
            target.dureeAttenteProduction = expected;
            actual = target.dureeAttenteProduction;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour minerai
        ///</summary>
        [TestMethod()]
        public void mineraiTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            int expected = 124;
            int actual;
            target.minerai = expected;
            actual = target.minerai;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour nourriture
        ///</summary>
        [TestMethod()]
        public void nourritureTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            int expected = 248;
            int actual;
            target.nourriture = expected;
            actual = target.nourriture;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour nourritureHab
        ///</summary>
        [TestMethod()]
        public void nourritureHabTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            int expected = 12;
            int actual;
            target.nourritureHab = expected;
            actual = target.nourritureHab;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour population
        ///</summary>
        [TestMethod()]
        public void populationTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            int expected = 15;
            int actual;
            target.population = expected;
            actual = target.population;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour ressources
        ///</summary>
        [TestMethod()]
        public void ressourcesTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            Dictionary<string, int> expected = new Dictionary<string, int>();
            Dictionary<string, int> actual;
            target.ressources = expected;
            actual = target.ressources;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour uniteEnCommande
        ///</summary>
        [TestMethod()]
        public void uniteEnCommandeTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            int expected = 3;
            int actual;
            target.uniteEnCommande = expected;
            actual = target.uniteEnCommande;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour unites
        ///</summary>
        [TestMethod()]
        public void unitesTest()
        {
            ImplementationJeu.Ville target = CreateVille();
            List<Unite> expected = new List<Unite>();
            target.caseSousLaVille.unites = expected;
            List<Unite> actual = target.unites;
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///Test pour choixCase
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void choixCaseTest()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(10,10));
            Civilisation civilisation = new CivilisationEII();
            ImplementationJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            target.population = 100;
            List<Case> lesCasesObtenuesDansLordre = new List<Case>();

            Case cObtenue = target.choixCase();
            if(cObtenue != null)
                lesCasesObtenuesDansLordre.Add(cObtenue);

            while (cObtenue != null)
            {
                cObtenue = target.choixCase();
                if (cObtenue != null)
                {
                    lesCasesObtenuesDansLordre.Add(cObtenue);
                    target.casesOccupees.Add(cObtenue);
                }
            }

            Assert.AreEqual(25, lesCasesObtenuesDansLordre.Count);
        }

        /// <summary>
        ///Test pour commanderUnite
        ///</summary>
        [TestMethod()]
        public void commanderUniteTest()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(10, 10));
            Civilisation civilisation = new CivilisationEII();
            ImplementationJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            target.uniteEnCommande = 0;
            target.ressources["nourriture"] = 500;
            target.ressources["minerai"] = 500;

            Erreurs e = target.commanderUnite(0);
            Assert.IsTrue(e.pasErreur);

            e = target.commanderUnite(1);
            Assert.IsTrue(e.pasErreur);
        }

        /// <summary>
        ///Test pour commanderUnite
        ///</summary>
        [TestMethod()]
        public void commanderUniteTest2()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(10, 10));
            Civilisation civilisation = new CivilisationEII();
            ImplementationJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            target.uniteEnCommande = 1;
            target.ressources["nourriture"] = 500;
            target.ressources["minerai"] = 500;

            Erreurs e = target.commanderUnite(1);
            Assert.IsFalse(e.pasErreur);

            e = target.commanderUnite(2);
            Assert.IsTrue(e.pasErreur);
        }

        /// <summary>
        ///Test pour commanderUnite
        ///</summary>
        [TestMethod()]
        public void commanderUniteTest3()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(10, 10));
            Civilisation civilisation = new CivilisationEII();
            ImplementationJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            target.uniteEnCommande = 0;
            target.ressources["nourriture"] = 500;
            target.ressources["minerai"] = 500;

            target.civi.chef = new DirecteurBEDAT(civilisation,c.coordo);
            target.civi.unites.Add(target.civi.chef);

            Erreurs e = target.commanderUnite(3);
            Assert.IsFalse(e.pasErreur);
        }

        /// <summary>
        ///Test pour creerHabitant
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void creerHabitantTest()
        {
            Case c = ImplementationJeu.Jeu.Instance.Carte.obtenirCase(new ImplementationJeu.Coordonnees(14, 14));
            Civilisation civilisation = new CivilisationEII();
            ImplementationJeu.Ville target = new ImplementationJeu.Ville(c, civilisation);
            target.nourritureHab = 50;
            target.uniteEnCommande = 0;
            target.ressources["nourriture"] = 49;
            int populaceAvant = target.population;
            target.creerHabitant();
            Assert.AreEqual(populaceAvant, target.population);
            Assert.AreEqual(49, target.ressources["nourriture"]);
            Assert.AreEqual(50, target.nourritureHab);

            target.uniteEnCommande = 2;
            target.ressources["nourriture"] = 51;
            target.creerHabitant();
            Assert.AreEqual(populaceAvant, target.population);
            Assert.AreEqual(51, target.ressources["nourriture"]);
            Assert.AreEqual(50, target.nourritureHab);

            target.uniteEnCommande = 3;
            target.ressources["nourriture"] = 51;
            target.creerHabitant();
            Assert.AreEqual(populaceAvant+1, target.population);
            Assert.AreEqual(0, target.ressources["nourriture"]);
            Assert.IsTrue(50 < target.nourritureHab);

        }

        /// <summary>
        ///Test pour creerUnite
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void creerUniteTest()
        {
            ImplementationJeu.Ville vi = (ImplementationJeu.Ville)ImplementationJeu.Jeu.Instance.Joueurs[0].civilisation.villes[0];
            vi.uniteEnCommande = 0;
            vi.dureeAttenteProduction = 0;
            vi.ressources["nourriture"] = 500;
            vi.ressources["minerai"] = 500;

            vi.creerUnite();
            Assert.AreEqual(500, vi.ressources["nourriture"]);
            Assert.AreEqual(500, vi.ressources["minerai"]);

        }

        /// <summary>
        ///Test pour creerUnite
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void creerUniteTest2()
        {
            ImplementationJeu.Ville vi = (ImplementationJeu.Ville)ImplementationJeu.Jeu.Instance.Joueurs[0].civilisation.villes[0];
            vi.uniteEnCommande = 1;
            vi.dureeAttenteProduction = 0;
            vi.ressources["nourriture"] = 500;
            vi.ressources["minerai"] = 500;

            vi.creerUnite();
            Assert.AreEqual(500, vi.ressources["nourriture"]);
            Assert.AreEqual(0, vi.ressources["minerai"]);
            Assert.AreEqual(0, vi.uniteEnCommande);
        }

        /// <summary>
        ///Test pour creerUnite
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void creerUniteTest3()
        {
            ImplementationJeu.Ville vi = (ImplementationJeu.Ville)ImplementationJeu.Jeu.Instance.Joueurs[0].civilisation.villes[0];
            vi.uniteEnCommande = 2;
            vi.dureeAttenteProduction = 0;
            vi.ressources["nourriture"] = 500;
            vi.ressources["minerai"] = 500;

            vi.creerUnite();
            Assert.AreEqual(0, vi.ressources["nourriture"]);
            Assert.AreEqual(0, vi.ressources["minerai"]);
            Assert.AreEqual(0, vi.uniteEnCommande);
        }

        /// <summary>
        ///Test pour creerUnite
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void creerUniteTest4()
        {
            ImplementationJeu.Ville vi = (ImplementationJeu.Ville)ImplementationJeu.Jeu.Instance.Joueurs[0].civilisation.villes[0];
            vi.uniteEnCommande = 3;
            vi.dureeAttenteProduction = 0;
            vi.ressources["nourriture"] = 500;
            vi.ressources["minerai"] = 500;

            vi.creerUnite();
            Assert.AreEqual(500, vi.ressources["nourriture"]);
            Assert.AreEqual(0, vi.ressources["minerai"]);
            Assert.AreEqual(0, vi.uniteEnCommande);
        }

        /// <summary>
        ///Test pour creerUnite
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void creerUniteTest5()
        {
            ImplementationJeu.Ville vi = (ImplementationJeu.Ville)ImplementationJeu.Jeu.Instance.Joueurs[0].civilisation.villes[0];
            vi.uniteEnCommande = 8;
            vi.dureeAttenteProduction = 12;
            vi.ressources["nourriture"] = 500;
            vi.ressources["minerai"] = 500;

            vi.creerUnite();
            Assert.AreEqual(500, vi.ressources["nourriture"]);
            Assert.AreEqual(500, vi.ressources["minerai"]);
            Assert.AreEqual(8, vi.uniteEnCommande);
            Assert.AreEqual(12, vi.dureeAttenteProduction);
        }

        /// <summary>
        ///Test pour jouerUnTour
        ///</summary>
        [TestMethod()]
        public void jouerUnTourTest()
        {
           Assert.Inconclusive("Cette méthode est utilisée par la vue console. Elle utilise les autres méthodes de la classe. Cf autres tests");
        }

        /// <summary>
        ///Test pour recolterRessouces
        ///</summary>
        [TestMethod()]
        [DeploymentItem("ModelingProject1Lib.exe")]
        public void recolterRessoucesTest()
        {
            ImplementationJeu.Ville vi = (ImplementationJeu.Ville) ImplementationJeu.Jeu.Instance.Joueurs[0].civilisation.villes[0];
            int resNourrCase = vi.caseSousLaVille.nourriture;
            int resMinerCase = vi.caseSousLaVille.minerai;
            int resAvantNour = vi.ressources["nourriture"];
            int resAvantMin = vi.ressources["minerai"];
            vi.recolterRessouces();
            Assert.AreEqual(resNourrCase + resAvantNour, vi.ressources["nourriture"]);
            Assert.AreEqual(resMinerCase + resAvantMin, vi.ressources["minerai"]);
        }

    }
}
